有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java即时与ZoneDateTime。转换到另一时区

我很难理解java。ZoneDateTime-Instant-LocalDateTime ,到目前为止,我只知道:

  • Instant介于两者之间
  • 瞬间(在我的理解中)是一个从时间点(UTC)开始的时间戳,一个与人类时间流相关的时间戳,但没有时区
  • 时区日期时间有时区
  • Instant没有时区,但可以在提供了时区信息的情况下处理它
  • LocalDate时间没有时区,无法处理区域,它是一个日期时间,与整个时间流(全局)的延续没有任何关联

下面是这个转换

val seoul = "Asia/Seoul"

val zoneId = ZoneId.of(seoul)
val now = ZonedDateTime.now()

val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)
val convertedInstant = now.toInstant().atZone(zoneId)

// expected output
println(convertedInstant.format(DateTimeFormatter.ofPattern(format)))

// not expected output
println(converted.format(DateTimeFormatter.ofPattern(format)))

输出

2021-05-02 03:15:13
2021-05-02 09:15:13

我试图将一个给定的时间转换为另一个时区,在这个用例中,用户移动到另一个时区,我需要更新有关存储日期的任何信息

为什么我得到的第二个值不正确。。?为什么我必须先将其转换为Instant,然后再进行转换

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    你的大多数子弹都是完全正确的。只是你不应该像你在第一个项目中说的那样,在{}和{}之间使用Instant。在InstantLocalDateTime之间转换需要一个时区(或至少与UTC的偏移量),因此应该经过ZonedDateTime。所以ZonedDateTime是在其他两个之间使用的。正如我所说,其余的都是正确的

    您并不完全清楚您对代码的期望,也不清楚更具体地观察到的结果有什么不同。假设你想在整个过程中使用相同的时间点,这一行就是你惊喜的地方:

    val convertedZoneDateTIme = ZonedDateTime.of(now.toLocalDateTime(), zoneId).withZoneSameInstant(ZoneOffset.UTC)
    

    now是您自己时区中的ZonedDateTime(确切地说是JVM的默认时区)。通过只取一天中的日期和时间,并将它们与不同的时区相结合,你就保留了一天中的时间,但通过这种方式(可能)改变了时间流中的时间点。接下来,您将转换为UTC,以保持时间点(瞬间),从而(可能)更改一天中的时间,也可能更改日期。你的起点ZonedDateTime已经一无所有,我看不出这个操作有什么意义。要将now转换为UTC,保持时间线上的点,请使用更简单的:

    val convertedZoneDateTIme = now.withZoneSameInstant(ZoneOffset.UTC)
    

    通过这个改变,你的两个输出在时间点上达成一致。输出示例:

    2021-05-07 02:30:16 +09:00 Korean Standard Time
    2021-05-06 17:30:16 +00:00 Z
    

    我使用了formatuuuu-MM-dd HH:mm:ss xxx zzzz

    另外,对于其他转换,我更喜欢使用withZoneSameInstant()。那么我们就不需要经过Instant

    val convertedInstant = now.withZoneSameInstant(zoneId)
    

    它给出与代码相同的结果

    简要概述所讨论的每门课程的内容:

    Class Date and time of day Point in time Time zone
    ^{} Yes Yes Yes
    ^{} - Yes -
    ^{} Yes - -

    基本上LocalDateTime对你的目的没有任何用处,而且Instant虽然可用,但也不是必需的ZonedDateTime单独满足你的需求